package com.eshore.norm.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.exceptions.ApiException;
import com.eshore.norm.enumeration.CloudTypeEnum;
import com.eshore.norm.enumeration.CmdbResTypeEnums;
import com.eshore.norm.enumeration.CmdbVmStatusEnum;
import com.eshore.norm.pojo.constant.Const;
import com.eshore.norm.pojo.dto.NormConfig;
import com.eshore.norm.pojo.dto.NormVm;
import com.eshore.norm.mapper.NormVmMapper;
import com.eshore.norm.pojo.dto.NormVmSecurityGroup;
import com.eshore.norm.pojo.po.*;
import com.eshore.norm.pojo.po.vm.NormSyncVmPO;
import com.eshore.norm.pojo.vo.SyncCmdbVmVO;
import com.eshore.norm.pojo.vo.norm_vm.NormVmPerformanceVO;
import com.eshore.norm.service.INormAddressGroupService;
import com.eshore.norm.service.INormVmService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.eshore.norm.service.NormVmSecurityGroupService;
import com.eshore.norm.util.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 单台云主机详情 服务实现类
 * </p>
 *
 * @author chenjl
 * @since 2024-01-05
 */
@Slf4j
@Service
public class NormVmServiceImpl extends ServiceImpl<NormVmMapper, NormVm> implements INormVmService {

    @Autowired
    private INormAddressGroupService addressGroupService;

    @Autowired
    private NormVmSecurityGroupService vmSecurityGroupService;

    @Override
    public void dataImport(NormServersDetailPO po) {
        log.info("云主机po：{}",po);
        List<NormServersDetailPO.ContentDTO.ServersDTO> poServers = po.getContent().get(0).getServers();
        if (CollectionUtils.isNotEmpty(poServers)){
            //开始处理源数据 将其包装成NormVm和NormVmSecurityGroup
            NormSyncVmPO syncVmPO = handleServers(Const.CONFIG_ID,poServers);
            //处理虚机
            List<NormVm> vmList = syncVmPO.getVmList();
            log.info("vmList:{}",vmList);
            List<String> newIds = vmList.stream().map(NormVm::getServerId).collect(Collectors.toList());
            List<String> removeVmIds = cleanVmOldData(Const.CONFIG_ID, newIds);
            getBaseMapper().insertOrUpdate(vmList);
            //TODO 同步到CMDB处理
            syncVmToCmdb(vmList,removeVmIds,Const.RESOURCE_ID,Const.TENANT_CODE);

            //处理虚机安全组关系
            List<NormVmSecurityGroup> vmSecurityGroupList = syncVmPO.getVmSecurityGroupList();
            vmSecurityGroupService.sync(Const.CONFIG_ID,vmSecurityGroupList);
        }
    }


    /**
     * 同步Vm信息到cmdb
     */
    public void syncVmToCmdb(List<NormVm> vmList, List<String> deleteStrIds, Long resourceId,Long tenantCode) {
        log.info("deleteStrIds:{}",deleteStrIds);
        if (CollectionUtils.isNotEmpty(vmList)) {
            List<SyncCmdbVmVO> syncList = vmList.stream().map(item -> {
                SyncCmdbVmVO vo = new SyncCmdbVmVO();
                BeanUtil.copyProperties(item, vo);
                vo.setResourceId(resourceId)
                        .setVmId(item.getServerId())
                        //.setMachineRoomId(machineRoomId)
                        .setResourceType(CmdbResTypeEnums.NORM)
                        //.setVmCpu(item.getFlavorVcpu())
                        //.setVmIp(item.getPrivateIp())
                        //.setVmFloatingIp(item.getFloatingIp())
                        .setAccountId(item.getConfigId())
                        .setVmMemory(String.valueOf(item.getFlavorRam()))
                        .setVmDisk(String.valueOf(item.getFlavorDisk()))
                        .setTenantCode(tenantCode)
                        .setCloudType(CloudTypeEnum.PRIVATE)
                        .setVmStatus(CmdbVmStatusEnum.manageOneCovert(item.getStatus()))
                        .setOsDesc(item.getName())
                        //.setVmUuid(item.getNativeId())
                        .setVmCreateDate(org.apache.commons.lang3.StringUtils.isNotBlank(item.getCreated()) ? DateUtils.formatUTCToBJDate(item.getCreated()) : null);
                return vo;
            }).collect(Collectors.toList());

            log.info("syncList:{}",syncList);
//            SyncMessageContent<SyncCmdbVmVO> messageContent = new SyncMessageContent<>();
//            messageContent.setCloudType(SyncMessageContent.CLOUD_TYPE_NORM_CLOUD);
//            messageContent.setResourceType(SyncMessageContent.RESOURCE_TYPE_SYNC_VM);
//            messageContent.setAddOrUpdateDatas(syncList);
//            messageContent.setRemoveStrIds(deleteStrIds);
//            rabbitService.defaultDirectSend(SyncMessageContent.QUEUE_NAME, JSONObject.toJSONString(messageContent));
        }
    }


    private List<String> cleanVmOldData(Long configId, List<String> newIds) {
        //查出原来的旧数据
        List<String> oldVmIds = lambdaQuery().eq(NormVm::getConfigId, configId).list().stream().map(NormVm::getServerId).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(oldVmIds)){
            oldVmIds.removeAll(newIds);
            if (CollectionUtils.isNotEmpty(oldVmIds)){
                lambdaUpdate().in(NormVm::getServerId).remove();
                return oldVmIds;
            }
        }
        return null;
    }

    private NormSyncVmPO handleServers(Long configId, List<NormServersDetailPO.ContentDTO.ServersDTO> poServers) {
        NormSyncVmPO po = new NormSyncVmPO();
        List<NormVm> vmList = new ArrayList<>();
        List<NormVmSecurityGroup> vmSecurityGroupList = new ArrayList<>();
        poServers.forEach(s -> {
            //先处理虚机基本数据
            NormVm vm = new NormVm();
            vm.setId(IdWorker.getId());
            vm.setConfigId(configId);
            vm.setCreateDate(DateUtil.parseUTC(s.getCreated()));
            vm.setUpdateDate(DateUtil.parseUTC(s.getUpdated()));
            vm.setAccessIPv4(s.getAccessIPv4());
            vm.setAccessIPv6(s.getAccessIPv6());
            vm.setCreated(s.getCreated());
            vm.setFlavorId(s.getFlavor().get(0).getId());
            vm.setFlavorVcpus(s.getFlavor().get(0).getVcpus());
            vm.setFlavorRam(s.getFlavor().get(0).getRam());
            vm.setFlavorDisk(s.getFlavor().get(0).getDisk());
            vm.setServerId(s.getId());
            vm.setName(s.getName());
            vm.setAvailabilityZone(s.getAvailabilityZone());
            vm.setHypervisorHostname(s.getHypervisorHostname());
            vm.setPowerState(s.getPowerState());
            vm.setStatus(s.getStatus());
            vm.setTenantId(s.getTenantId());
            vm.setUpdated(s.getUpdated());
            vm.setUserId(s.getUserId());
            vm.setLocked(s.getLocked());
            vmList.add(vm);
            List<NormServersDetailPO.ContentDTO.ServersDTO.SecurityGroupsDTO> securityGroups = s.getSecurityGroups();
            if (CollectionUtils.isNotEmpty(securityGroups)){
                securityGroups.forEach(sg -> {
                    NormVmSecurityGroup vmSecurityGroup = new NormVmSecurityGroup();
                    vmSecurityGroup.setId(IdWorker.getId());
                    vmSecurityGroup.setConfigId(configId);
                    vmSecurityGroup.setVmId(s.getId());
                    vmSecurityGroup.setSecurityGroupId(addressGroupService.getGroupIdByName(sg.getName(),s.getTenantId()));
                    vmSecurityGroup.setCreateDate(new Date());
                    vmSecurityGroupList.add(vmSecurityGroup);
                });
            }
        });
        po.setVmList(vmList);
        po.setVmSecurityGroupList(vmSecurityGroupList);
        return po;
    }

    @Override
    public NormVmPerformanceVO fechVmPerformance(String vmId) {
        NormVmPerformanceVO result = new NormVmPerformanceVO();
//        //先校验虚机是否存在
//        if (!checkVmExit(vmId)) {
//            throw new ApiException(ErrorCodeConsts.NOT_EXIT, "云主机");
//        }
//        NormVm normVm = lambdaQuery().eq(NormVm::getServerId, vmId).one();
//        Long configId = normVm.getConfigId();
//        NormConfig config = configService.getConfigById(configId);
//        //获取云主机监控
//        String vmUrl = StringUtils.replace(NormURLConsts.VM_MONITOR_URL, "{vmId}", vmId);
//        configService.handleHttpRequestParam(config, vmUrl);
//        NormApi n1 = NormFeigns.normScope(NormApi.class, config);
//        NormVmMonitorPO vmMonitorPO = n1.getVmMonitor(vmId);
//        if (vmMonitorPO != null && vmMonitorPO.getStatus() == 200){
//            NormVmMonitorPO.ContentDTO vmContentDTO = vmMonitorPO.getContent().get(0);
//            result.setCpuUsage(vmContentDTO.getCpuUsage());
//            result.setMemUsedPercent(vmContentDTO.getMemUsedPercent());
//            result.setAverBytesRecvRate(vmContentDTO.getAverBytesRecvRate());
//            result.setAverBytesSentRate(vmContentDTO.getAverBytesSentRate());
//        }
//
//        //获取硬盘监控
//        String storageUrl = StringUtils.replace(NormURLConsts.STORAGE_MONITOR_URL, "{vmId}", vmId);
//        configService.handleHttpRequestParam(config, storageUrl);
//        NormApi n2 = NormFeigns.normScope(NormApi.class, config);
//        NormStorageMonitorPO storageMonitorPO = n2.getStorageMonitor(vmId);
//        if (storageMonitorPO != null && storageMonitorPO.getStatus() == 200){
//            List<NormStorageMonitorPO.ContentDTO> content = storageMonitorPO.getContent();
//            //处理硬盘利用率 为利用率统计做兼容
//            double used = content.stream().mapToDouble(NormStorageMonitorPO.ContentDTO::getUsed).sum();
//            double total = content.stream().mapToDouble(NormStorageMonitorPO.ContentDTO::getTotal).sum();
//            result.setDiskUsed(used/total);
//            result.setStorageMonitorList(content);
//        }else {
//            result.setDiskUsed(0.0);
//        }
//
//        //获取弹性Ip监控
//        List<String> ipIds = vmSecurityGroupService.getFloatipIdByVmId(vmId);
//        if (CollectionUtils.isNotEmpty(ipIds)){
//            List<NormFloatipMonitorPO.ContentDTO> contentAll = new ArrayList<>();
//            ipIds.forEach(ipId -> {
//                String ipUrl = StringUtils.replace(NormURLConsts.FLOATIP_MONITOR_URL, "{uuid}", ipId);
//                configService.handleHttpRequestParam(config, ipUrl);
//                NormApi n3 = NormFeigns.normScope(NormApi.class, config);
//                List<NormFloatipMonitorPO.ContentDTO> content = n3.getFloatipMonitor(ipId).getContent();
//                if (CollectionUtils.isNotEmpty(content)){
//                    contentAll.addAll(content);
//                }
//            });
//            result.setFloatipMonitorList(contentAll);
//        }
        return result;
    }

    /**
     * ture代表存在  flase代表不存在
     * @param vmId
     * @return
     */
    private boolean checkVmExit(String vmId) {
        return lambdaQuery().eq(NormVm::getServerId,vmId).one() != null;
    }

    @Override
    public List<String> getUuidListByConfigId(Long configId) {
        return lambdaQuery()
                .eq(NormVm::getConfigId,configId)
                .list()
                .stream()
                .map(NormVm::getServerId)
                .collect(Collectors.toList());
    }
}
